﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using System.Data.Common;
using System.Data.SqlClient;

namespace NewBee.Core.Data
{
    public class DbHelper
    {
        #region 资源定义
        /// <summary>
        /// 数据库连接
        /// </summary>
        public DbProviderFactory _DbProviderFactory;    //数据库连接
        /// <summary>
        /// 读写连接字符串
        /// </summary>
        public string _ConnectionString;                //读写连接字符串
        /// <summary>
        /// 只读连接字符串
        /// </summary>
        public string _QueryConnectionString;           //只读连接字符串
        /// <summary>
        /// 数据库驱动类型
        /// </summary>
        public string _DriverType;                      //数据库驱动类型
        #endregion

        #region 初始化
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="queryConnectionString"></param>
        /// <param name="driverType"></param>
        public DbHelper(string connectionString, string queryConnectionString, string driverType)
        {
            _DbProviderFactory = SqlClientFactory.Instance;
            _ConnectionString = connectionString;
            _QueryConnectionString = queryConnectionString;
            _DriverType = driverType;
        }
        #endregion

        public SQLBuilder.Sql Sql(string sql)
        {
            return new SQLBuilder.Sql(this, sql);
        }

        public SQLBuilder.Insert Insert(string tableName)
        {
            return new SQLBuilder.Insert(this, tableName);
        }

        //public SQLBuilder.Insert Insert(string tableName,string PrimaryKey)
        //{
        //    return new SQLBuilder.Insert(this, tableName, PrimaryKey);
        //}

        public SQLBuilder.Insert_T<T> Insert<T>(T model)
        {
            return new SQLBuilder.Insert_T<T>(this, typeof(T).Name, model, string.Empty);
        }

        public SQLBuilder.Insert_T<T> Insert<T>(T model, string PrimaryKey)
        {
            return new SQLBuilder.Insert_T<T>(this, typeof(T).Name, model, PrimaryKey);
        }

        public SQLBuilder.Insert_T<T> Insert<T>(string tableName, T model, string PrimaryKey)
        {
            return new SQLBuilder.Insert_T<T>(this, tableName, model, PrimaryKey);
        }

        public SQLBuilder.Update Update(string tableName)
        {
            return new SQLBuilder.Update(this, tableName);
        }
        public SQLBuilder.Update_T<T> Update<T>(T model)
        {
            return new SQLBuilder.Update_T<T>(this, typeof(T).Name, model);
        }

        public SQLBuilder.Update_T<T> Update<T>(string tableName, T model)
        {
            return new SQLBuilder.Update_T<T>(this, tableName, model);
        }

        public SQLBuilder.Delete Delete(string tableName)
        {
            return new SQLBuilder.Delete(this, tableName);
        }

        public SQLBuilder.Select Select(string tableName, string colums)
        {
            return new SQLBuilder.Select(this, tableName, colums);
        }

        public SQLBuilder.Select_T<T> Select<T>(string tableName, string colums)
        {
            return new SQLBuilder.Select_T<T>(this, tableName, colums);
        }
        public SQLBuilder.Select_T<T> Select<T>( string colums)
        {
            return new SQLBuilder.Select_T<T>(this, typeof(T).Name, colums);
        }
        #region 方法
        /// <summary>
        /// 执行增删改sql语句
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public int Execute(string sql, object param)
        {
            if (string.IsNullOrEmpty(sql))
                return -101;

            using (var db = _DbProviderFactory.CreateConnection())
            {
                db.ConnectionString = _ConnectionString;
                db.Open();
                int _int = db.Execute(sql, param);

                db.Close();
                return _int;
            }
        }

        /// <summary>
        /// 执行查询SQL语句，返回第一行（只读库）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public T QueryFirst<T>(string sql, object param)
        {
            try
            {
                using (var db = _DbProviderFactory.CreateConnection())
                {
                    db.ConnectionString = _QueryConnectionString;
                    db.Open();
                    T result = db.Query<T>(sql, param).FirstOrDefault();

                    db.Close();
                    return result;
                }
            }
            catch (Exception ex)
            {
                LogHelper.SetExceptionLog(ex);
                return default(T);
            }
        }

        /// <summary>
        /// 执行查询SQL语句，返回第一行（读写库）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public T QueryFirstForWrite<T>(string sql, object param)
        {
            try
            {
                using (var db = _DbProviderFactory.CreateConnection())
                {
                    db.ConnectionString = _ConnectionString;
                    db.Open();
                    T result = db.Query<T>(sql, param).FirstOrDefault();

                    db.Close();
                    return result;
                }
            }
            catch (Exception ex)
            {
                LogHelper.SetExceptionLog(ex);
                return default(T);
            }
        }


        /// <summary>
        /// 执行查询SQL语句，返回数据实体（只读库）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public IEnumerable<T> Query<T>(string sql, object param)
        {
            try
            {
                using (var db = _DbProviderFactory.CreateConnection())
                {
                    db.ConnectionString = _QueryConnectionString;
                    db.Open();
                    IEnumerable<T> result = db.Query<T>(sql, param);

                    db.Close();
                    return result;
                }
            }
            catch (Exception ex)
            {
                LogHelper.SetExceptionLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 执行查询SQL语句，返回数据实体（读写库）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public IEnumerable<T> QueryForWrite<T>(string sql, object param)
        {
            try
            {
                using (var db = _DbProviderFactory.CreateConnection())
                {
                    db.ConnectionString = _ConnectionString;
                    db.Open();
                    IEnumerable<T> result = db.Query<T>(sql, param);

                    db.Close();
                    return result;
                }
            }
            catch (Exception ex)
            {
                LogHelper.SetExceptionLog(ex);
                return null;
            }
        }

        #endregion
    }
}
